package com.gzx.qc.modular.asr.strategy.baidu.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gzx.qc.modular.asr.strategy.baidu.dto.BaiduAsrTextRespDto;
import com.gzx.qc.modular.asr.strategy.baidu.dto.BaiduChatRespDto;
import com.gzx.qc.modular.asr.strategy.baidu.dto.BaiduCreateTaskRespDto;
import com.gzx.qc.modular.asr.strategy.baidu.dto.BaiduTokenRespDto;
import com.gzx.qc.modular.asr.strategy.baidu.enums.BaiduTaskTypeEnum;
import com.gzx.qc.modular.asr.strategy.baidu.properties.BaiduProperties;
import com.gzx.qc.modular.asr.strategy.baidu.service.GzxBaiduService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.util.CommonHttpUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author zjt
 * @description
 * @date 2025/7/29 10:19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GzxBaiduServiceImpl implements GzxBaiduService {

    private static final String ACCESS_TOKEN = "access_token";
    private static final String BAIDU_ASR_TOKEN = "baidu_asr_token";
    private final BaiduProperties.ASR baiduAsrProperties;
    private final BaiduProperties.Chat baiduChatProperties;
    private final CommonCacheOperator cacheOperator;
    private final RedissonClient redissonClient;

    public static void main(String[] args) {
        queryCheck();
    }

    private static void toCheck() {
        String token = "24.c46ec668e4ff3362cd3b7fd1ff97ffa9.2592000.1756548644.282335-119632845";
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("pid", 80006);
        bodyMap.put("speech_url", "https://saas-cti.htrxcall.com/recfile53/20250731/202507312006101785255304151753963570.wav");
        bodyMap.put("session_id", "123456nodatatest");
        bodyMap.put("sample_rate", 8000);
        bodyMap.put("role_num", 2);
        bodyMap.put("enable_detection", true);
        bodyMap.put("enable_detection_detail", true);
        bodyMap.put("is_split_channel", true);
        CommonHttpUtil.post("http://aip.baidubce.com/rest/2.0/speech/publiccloudspeech/v1/voice/detection?" + ACCESS_TOKEN + "=" + token, null, JSON.toJSONString(bodyMap), null);
    }

    private static void queryCheck() {
        String token = "24.c46ec668e4ff3362cd3b7fd1ff97ffa9.2592000.1756548644.282335-119632845";
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("session_id", "123456nodatatest");
        bodyMap.put(ACCESS_TOKEN, token);
        CommonHttpUtil.post("http://aip.baidubce.com/rest/2.0/speech/publiccloudspeech/v1/voice/detection/result", null, JSON.toJSONString(bodyMap), null);
    }

    /**
     * 创建音频转写任务
     *
     * @param speechUrl 文件地址
     * @return
     */
    @Override
    public String createTask(BaiduTaskTypeEnum baiduTaskTypeEnum, String speechUrl) {
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("speech_url", speechUrl);
        bodyMap.put("format", "wav");
        bodyMap.put("pid", 1134);
        bodyMap.put("rate", 8000);
        bodyMap.put("channel", 2);
        try {
            String resp = CommonHttpUtil.post(baiduAsrProperties.getUrl() + baiduTaskTypeEnum.getType() + "?" + ACCESS_TOKEN + "=" + getAccessToken(), null, JSON.toJSONString(bodyMap), baiduTaskTypeEnum.getDesc());
            BaiduCreateTaskRespDto baiduCreateTaskRespDto = JSONObject.parseObject(resp, BaiduCreateTaskRespDto.class);
            if (baiduCreateTaskRespDto != null && StringUtils.isNotBlank(baiduCreateTaskRespDto.getTask_id())) {
                return baiduCreateTaskRespDto.getTask_id();
            }
            log.error("{}出现异常：{}", baiduTaskTypeEnum.getDesc(), baiduCreateTaskRespDto);
            return null;
        } catch (Exception e) {
            log.error("{}出现异常：", baiduTaskTypeEnum.getDesc(), e);
            return null;
        }
    }

    /**
     * 同步语音转写任务
     *
     * @param baiduTaskTypeEnum
     * @param taskIdList
     * @return
     */
    @Override
    public List<BaiduAsrTextRespDto.BaiduAsrTaskInfo> syncTaskResult(BaiduTaskTypeEnum baiduTaskTypeEnum, List<String> taskIdList) {
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("task_ids", taskIdList);
        String resp = CommonHttpUtil.post(baiduAsrProperties.getUrl() + baiduTaskTypeEnum.getType() + "?" + ACCESS_TOKEN + "=" + getAccessToken(), null, JSON.toJSONString(bodyMap), baiduTaskTypeEnum.getType());
        BaiduAsrTextRespDto baiduAsrTextRespDto = JSONObject.parseObject(resp, BaiduAsrTextRespDto.class);
        if (baiduAsrTextRespDto != null && CollectionUtil.isNotEmpty(baiduAsrTextRespDto.getTasks_info())) {
            return baiduAsrTextRespDto.getTasks_info();
        }
        return List.of();
    }

    /**
     * 分析语音文本（AI对话）
     *
     * @param content
     */
    @Override
    public BaiduChatRespDto.Choice.Message unparkVoiceText(BaiduTaskTypeEnum baiduTaskTypeEnum, String content) {
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("model", "ernie-x1-turbo-32k");
        bodyMap.put("messages", List.of(Map.of("role", "user", "content", content)));
        try {
            String resp = CommonHttpUtil.postWithTimeOut(baiduChatProperties.getUrl(), Map.of("Authorization", "Bearer " + baiduChatProperties.getToken()), JSON.toJSONString(bodyMap), baiduTaskTypeEnum.getDesc(), 50000);
            BaiduChatRespDto baiduChatRespDto = JSONObject.parseObject(resp, BaiduChatRespDto.class);
            if (baiduChatRespDto != null && CollectionUtil.isNotEmpty(baiduChatRespDto.getChoices())) {
                return baiduChatRespDto.getChoices().getFirst().getMessage();
            }
            log.error("{}出现异常：{}", baiduTaskTypeEnum.getDesc(), baiduChatRespDto);
            return null;
        } catch (Exception e) {
            log.error("{}出现异常：", baiduTaskTypeEnum.getDesc(), e);
            return null;
        }
    }

    private String getAccessToken() {
        String baiduToken = cacheOperator.getCatchString(BAIDU_ASR_TOKEN);
        if (StringUtils.isNotBlank(baiduToken)) {
            return baiduToken;
        }
        // 获取分布式锁
        RLock rLock = redissonClient.getLock(BAIDU_ASR_TOKEN + "_lock");
        try {
            // 尝试加锁，等待时间5秒，锁有效期30秒
            boolean locked = rLock.tryLock(5, 15, TimeUnit.SECONDS);
            if (locked) {
                // 双重检查，防止其他线程已经更新了token
                baiduToken = cacheOperator.getCatchString(BAIDU_ASR_TOKEN);
                if (StringUtils.isBlank(baiduToken)) {
                    // 调用企业微信接口获取新token
                    BaiduTokenRespDto baiduTokenRespDto = httpGetAccessToken();
                    if (baiduTokenRespDto != null && StringUtils.isNotBlank(baiduTokenRespDto.getAccess_token()) && baiduTokenRespDto.getExpires_in() > 600) {
                        cacheOperator.setCatchString(BAIDU_ASR_TOKEN, baiduTokenRespDto.getAccess_token(), (long) baiduTokenRespDto.getExpires_in() - 120);
                        baiduToken = baiduTokenRespDto.getAccess_token();
                    } else {
                        log.error("获取百度AccessToken出现异常");
                    }
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new CommonException("获取百度AccessToken时被中断", e);
        }
        return baiduToken;
    }

    private BaiduTokenRespDto httpGetAccessToken() {
        String resp = CommonHttpUtil.post("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + baiduAsrProperties.getKey() + "&client_secret=" + baiduAsrProperties.getSecret(), null, null, "获取百度Token");
        return JSONObject.parseObject(resp, BaiduTokenRespDto.class);
    }
}
